feat(examples): add CodeBuddy Code CLI integration example(refs #644 ) - #996
feat(examples): add CodeBuddy Code CLI integration example(refs #644 )#996pei-pei45 wants to merge 12 commits into
Conversation
Review: feat(examples): add CodeBuddy Code CLI integration example (PR #996)This review is AI-generated and does not represent human approval. OverviewThis PR adds a substantial CodeBuddy Code CLI integration example (5,629 additions across 25 files). It includes a Docker image, host-side executor scripts, an MCP server, a CodeBuddy bash-routing plugin with installer, comprehensive documentation in both English and Chinese, a CI workflow, and a 166-test pytest suite. The architecture follows the sound "keep the LLM agent on the host, route dangerous operations into a disposable VM" pattern. The overall quality is high — the code is well-structured, security-conscious (path validation, symlink rejection, session file hardening, credential separation), thoroughly tested, and well-documented. Below are issues I recommend addressing. Findings (ranked by severity)Medium1. CI workflow leaks container on exec failure ( The workflow starts a daemon container with Failure scenario: A transient npm install failure causes Suggested fix: Add a cid=""
cleanup() { [ -n "$cid" ] && docker rm -f "$cid" 2>/dev/null || true; }
trap cleanup EXIT
cid=$(docker run -d --rm codebuddy-cube:ci)2. The MCP server defines its own Suggested fix: Refactor the common 3. Package name regex rejects valid PEP 508 names ( The regex r"^[A-Za-z0-9]([A-Za-z0-9._-]*[A-Za-z0-9])?$|^[A-Za-z0-9]$"PEP 508 allows trailing Low4. Container lifecycle: The workflow passes 5. The MCP protocol defines 6. The module docstring says it's "SDK-agnostic (duck-typed on sandbox.commands.run)," but line 1540 imports Notes7. Session file TOCTOU is acknowledged but not eliminated ( The code includes a detailed comment about the TOCTOU race between FileExistsError 8. Input validation is thorough and correct Path traversal prevention ( 9. Test coverage is strong The 166-test suite covers both success paths and failure modes (empty input, oversized input, non-string input, invalid paths, symlink rejection, SDK errors, stream writing edge cases). Tests are fully offline via mocking. SummaryThis is a well-crafted integration example that demonstrates deep understanding of the CubeSandbox security model. The three medium findings (CI cleanup, code duplication, PEP 508 regex) are worth addressing. No blocking issues were found. |
… and credential vault
.env.example documents CUBE_API_URL / CUBE_API_KEY as the canonical names
with E2B_* as legacy aliases, but several files only read E2B_* and would
silently use defaults when a user configures via .env.example as-is.
Changes:
- env_utils.py: add cube_required(cube_name, legacy_name) helper that checks
canonical name before legacy name and emits a clear error if neither is set.
- run_codebuddy.py, resume_codebuddy.py, network_policy.py: replace the two
required("E2B_") calls with cube_required("CUBE_API_URL", "E2B_API_URL")
and cube_required("CUBE_API_KEY", "E2B_API_KEY").
- .env.example, README.md, README_zh.md: update variable names to canonical.
Existing deployments that only set E2B_* continue to work unchanged.
Assisted-by: AGENT_NAME:claude-opus-4-8
Co-authored-by: Cursor <cursoragent@cursor.com>
6ba00e1 to
82657fe
Compare
| # add a retry loop because envd may still be booting on cold cache. | ||
| for i in $(seq 30); do | ||
| if docker exec "$cid" curl -fsS -o /dev/null \ | ||
| http://127.0.0.1:49983/health; then |
There was a problem hiding this comment.
Potential orphan container on exec failure
If docker exec "$cid" codebuddy --version (or any later docker exec) returns a non-zero exit, the shell exits before reaching docker rm -f "$cid" on line 86. The --rm flag only removes the container after its main process exits, which won't happen for a daemon. Container stays alive until the runner reaps it.
Consider adding a trap at the top of this run: block:
cid=""
cleanup() { [ -n "$cid" ] && docker rm -f "$cid" 2>/dev/null || true; }
trap cleanup EXIT
cid=$(docker run -d --rm codebuddy-cube:ci)This guarantees cleanup regardless of which command fails.
There was a problem hiding this comment.
This job runs on GitHub-hosted ubuntu-latest runners, which are fully ephemeral — the VM is destroyed once the job finishes, so an orphaned container here doesn't persist or accumulate across runs. Since this is the only container operation in the static job, I'll leave it as-is for now, but agree the trap pattern would be worth adding if this ever moves to a self-hosted runner or if more container steps are added to this job later.
| try: | ||
| result = _get_sandbox().commands.run(cmd, timeout=timeout) | ||
| return { | ||
| "exit_code": result.exit_code, |
There was a problem hiding this comment.
Duplicated run_command — diverges from _codebuddy_common
mcp_server.py defines its own run_command() (returning a dict) while _codebuddy_common.run_command() does essentially the same thing (returning an SDK result object). Any bug fix or improvement to the shared helper will not apply here.
Suggested approach: either refactor _codebuddy_common.run_command() to optionally return a dict, or have this function call the shared helper and convert the result. At minimum leave a docstring cross-reference so future maintainers know both copies exist.
There was a problem hiding this comment.
Fair point on the duplication. Given mcp_server.py needs a dict-shaped return (for JSON-RPC serialization) while _codebuddy_common.run_command() returns an SDK result object, I'll leave them separate for now but will add a docstring cross-reference noting both copies exist, so future maintainers aren't surprised.
|
|
||
| # PEP 508 package name validator — compiled once at module load. | ||
| _PACKAGE_NAME_RE = re.compile(r"^[A-Za-z0-9]([A-Za-z0-9._-]*[A-Za-z0-9])?$|^[A-Za-z0-9]$") | ||
|
|
There was a problem hiding this comment.
Package name regex rejects valid PEP 508 names
PEP 508 allows trailing ._- characters (e.g., foo_), but this regex requires the name to end with [A-Za-z0-9]. The comment says "be conservative" which is a reasonable security choice, but users hitting this with legitimate package names may not understand why they're blocked.
Recommend either expanding the regex to match the full PEP 508 spec, or adding an explicit comment noting this is a deliberate restriction (not a bug) so future maintainers don't "fix" it without understanding the security rationale.
There was a problem hiding this comment.
This is intentional — the conservative pattern is a deliberate security choice to reject ambiguous package names rather than a bug. Will add an explicit comment above the regex noting this so it doesn't get "fixed" by a future contributor without context.
feat(examples): add CodeBuddy Code CLI integration example(refs #644 )
CodeBuddy Sandbox Integration
Summary
Add a complete sandbox execution backend that lets CodeBuddy run untrusted code in isolated CubeSandbox MicroVMs. The architecture follows the "keep the LLM agent on the host, route dangerous operations into a disposable VM" pattern.
What's Changed
sandbox_exec.py— Host-side CLI executor--code/--file/--cmd/--pipfor Python, file execution, and shell commands/tmp/cubesandbox_codebuddy_session_<uid>,0600,O_NOFOLLOW)cwd), rejects symlinksthreading.Lockmcp_server.py— MCP server (JSON-RPC over stdio)Five tools exposed:
sandbox_run_codesandbox_run_commandsandbox_write_filesandbox_read_filesandbox_reset/workspace,/tmp,/home/user)timeout(max 300 s) and content sizes (code: 100 KB, content: 1 MB)hooks/— CodeBuddy bash-routing plugincubesandbox-sandbox.jsintercepts thebashtool and routes it throughsandbox_exec.pyinstall.shcopies the plugin to~/.config/codebuddy/plugins/and merges only allow-listedCUBE_*keys into the CodeBuddy config (provider API keys are never copied)tests/— pytest suite (166 tests, fully offline)test_sandbox_exec.py— exec API, sandbox lifecycle, path validation, symlink rejectiontest_mcp_server.py— request handling, tool calls, validation, error pathstest_codebuddy_common.py— helpers, stream writer, command executiontest_env_utils.py— pre-existing env utility testsSecurity
os.path.realpathresolutionO_NOFOLLOW+O_EXCLon session filethreading.Lockon sandbox accessTesting
Assisted-by: Cursor:composer-2.5-fast





Signed-off-by: YanxuanLiu 3205348955@qq.com